/*
 * GStreamer Enrigin Encoder Plugin (Direct FFmpeg Implementation)
 * 直接基于FFmpeg VSV编码器，不依赖OTL
 * 
 * 功能：使用FFmpeg的h264_vsv_encoder/hevc_vsv_encoder进行硬件编码
 * 用法：gst-launch-1.0 videotestsrc ! enriginenc ! filesink location=output.h264
 */

#ifndef __GST_ENRIGINENC_H__
#define __GST_ENRIGINENC_H__

#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/gstvideoencoder.h>

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavutil/hwcontext.h>
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>
}

G_BEGIN_DECLS

#define GST_TYPE_ENRIGINENC (gst_enriginenc_get_type())
#define GST_ENRIGINENC(obj) \
  (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_ENRIGINENC, GstEnriginEnc))
#define GST_ENRIGINENC_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_ENRIGINENC, GstEnriginEncClass))
#define GST_IS_ENRIGINENC(obj) \
  (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_ENRIGINENC))
#define GST_IS_ENRIGINENC_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_ENRIGINENC))

typedef struct _GstEnriginEnc GstEnriginEnc;
typedef struct _GstEnriginEncClass GstEnriginEncClass;

struct _GstEnriginEnc
{
  GstVideoEncoder parent;

  /* Properties */
  gchar *codec_name;        // "h264" or "hevc"
  gint bitrate;             // in kbps
  gint gop_size;            // GOP size (VSV only supports 1)
  gchar *preset;            // encoding preset
  gchar *profile;           // encoding profile
  gchar *rc_mode;           // rate control mode: cbr, vbr, abr
  gchar *level;             // encoding level
  gboolean enable_cabac;    // enable CABAC
  gint card_id;             // card ID
  gint vpu_id;              // VPU ID
  gint fps_num;             // framerate numerator
  gint fps_den;             // framerate denominator

  /* FFmpeg encoder context */
  AVCodecContext *avctx;
  const AVCodec *codec;
  AVBufferRef *hw_device_ctx;
  AVFrame *sw_frame;        // software frame for input
  AVFrame *hw_frame;        // hardware frame for encoding
  
  /* Video info */
  GstVideoInfo info;
  gint width;
  gint height;
  enum AVPixelFormat sw_pix_fmt;
  
  /* State */
  gboolean encoder_initialized;
  gint64 frame_count;
  
  /* Frame queue for handling encoder delays */
  GQueue *pending_frames;  // Queue of GstVideoCodecFrame waiting for output
};

struct _GstEnriginEncClass
{
  GstVideoEncoderClass parent_class;
};

GType gst_enriginenc_get_type(void);

G_END_DECLS

#endif /* __GST_ENRIGINENC_H__ */
